# -*- coding: utf-8 -*-
#
# The Philatelist program is a fork of the OpenNumismat program
# Copyright (c) 2011 - 2024 Vitaly Ignatov (OpenNumismat) <opennumismat@gmail.com>
# Copyright (c) 2021 - 2024 Victor Nabatov (Philatelist) <nabatov.victor@gmail.com>
#

from PySide6.QtCore import Qt, QSettings
from PySide6.QtSql import QSqlQuery
from PySide6.QtWidgets import QCheckBox, QDialog, QDialogButtonBox, QMessageBox, QVBoxLayout

from Philatelist.Collection.CollectionFields import ImagesFields, TraitsImagesFields
from Philatelist.StampEditor.DetailsTabWidget import FormDetailsTabWidget
from Philatelist.StampEditor.FormItems import LineEditRef
from Philatelist.Tools.DialogDecorators import storeDlgSizeDecorator
from Philatelist.Tools.Converters import stringToMoney


@storeDlgSizeDecorator
class StampEditor(QDialog):

    def __init__(self, model, record, parent=None, usedFields=None):
        super().__init__(parent, Qt.WindowCloseButtonHint | Qt.WindowSystemMenuHint)
        self.clickedButton = QDialogButtonBox.Abort
        self.usedFields = usedFields
        self.record = record
        self.model = model
        self.tab = FormDetailsTabWidget(model, self, usedFields)
        self.items = self.tab.items
        self.textChangedTitle()
        self.tab.items['title'].widget().textChanged.connect(self.textChangedTitle)
        self.tab.fillItems(record)

        self.buttonBox = QDialogButtonBox(Qt.Horizontal)
        self.buttonBox.addButton(QDialogButtonBox.Save)
        self.buttonBox.addButton(QDialogButtonBox.Cancel)
        self.buttonBox.accepted.connect(self.save)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.clicked.connect(self.clicked)

        layout = QVBoxLayout()
        layout.addWidget(self.tab)
        layout.addWidget(self.buttonBox)
        self.setLayout(layout)

    def clicked(self, button):
        buttons = (
            QDialogButtonBox.Save,
            QDialogButtonBox.SaveAll,
            QDialogButtonBox.Cancel,
            QDialogButtonBox.Abort
        )
        for btn in buttons:
            if self.buttonBox.button(btn) == button:
                self.clickedButton = btn

    # Enable 'Save all' button
    def setManyStamps(self, many=True):
        if many:
            self.buttonBox.addButton(QDialogButtonBox.SaveAll)
            self.buttonBox.addButton(QDialogButtonBox.Abort)

    def textChangedTitle(self, text=''):
        if self.usedFields:
            title = [self.tr("Multi edit"), ]

        elif self.record.isNull('id'):
            title = [self.tr("New"), ]
        else:
            title = [self.tr("Edit"), ]

        if text:
            title.insert(0, text)

        self.setWindowTitle(' - '.join(title))

    def save(self):
        # Clear unused fields
        status = self.items['status'].widget().data()
        if status in ('demo', 'wish', 'rarity'):
            for key in ('pay_date', 'pay_price', 'total_pay_price', 'seller', 'pay_place', 'pay_info'):
                self.items[key].clear()

        if status in ('demo', 'wish', 'owned', 'sale', 'ordered', 'exchange', 'duplicate', 'rarity', 'variety'):
            for key in ('sale_date', 'sale_price', 'total_sale_price', 'buyer', 'sale_place', 'sale_info'):
                self.items[key].clear()

        settings = QSettings()
        key = 'show_info/save_without_title'
        show = settings.value(key, True, type=bool)
        if show:
            if not self.usedFields:
                if not self.items['title'].value():
                    msg_box = QMessageBox(
                        QMessageBox.Warning,
                        self.tr("Save"),
                        self.tr("Stamp title not set. Save without title?"),
                        QMessageBox.Save | QMessageBox.No,
                        self
                    )
                    msg_box.setDefaultButton(QMessageBox.No)
                    cb = QCheckBox(self.tr("Don't show this again"))
                    msg_box.setCheckBox(cb)
                    result = msg_box.exec_()
                    if result != QMessageBox.Save:
                        return
                    else:
                        if cb.isChecked():
                            settings.setValue(key, False)

        # Checking that TotalPrice not less than Price
        pay_price_str = self.items['pay_price'].value()
        total_pay_price_str = self.items['total_pay_price'].value()
        if total_pay_price_str:
            total_pay_price = stringToMoney(total_pay_price_str)
            if total_pay_price < 0:
                result = QMessageBox.warning(
                    self,
                    self.tr("Save"),
                    self.tr("Total paid price is negative. Save?"),
                    QMessageBox.Save | QMessageBox.No,
                    QMessageBox.No
                )
                if result != QMessageBox.Save:
                    return

        if pay_price_str and total_pay_price_str:
            pay_price = stringToMoney(pay_price_str)
            if total_pay_price < pay_price:
                result = QMessageBox.warning(
                    self,
                    self.tr("Save"),
                    self.tr("Pay price is great than total paid price. Save?"),
                    QMessageBox.Save | QMessageBox.No,
                    QMessageBox.No
                )
                if result != QMessageBox.Save:
                    return

        sale_price_str = self.items['sale_price'].value()
        total_sale_price_str = self.items['total_sale_price'].value()
        if total_sale_price_str:
            total_sale_price = stringToMoney(total_sale_price_str)
            if total_sale_price < 0:
                result = QMessageBox.warning(
                    self,
                    self.tr("Save"),
                    self.tr("Total revenue price is negative. Save?"),
                    QMessageBox.Save | QMessageBox.No,
                    QMessageBox.No
                )
                if result != QMessageBox.Save:
                    return

        if sale_price_str and total_sale_price_str:
            sale_price = stringToMoney(sale_price_str)
            if sale_price < total_sale_price:
                result = QMessageBox.warning(
                    self,
                    self.tr("Save"),
                    self.tr("Sale price is less than total revenue price. Save?"),
                    QMessageBox.Save | QMessageBox.No,
                    QMessageBox.No
                )
                if result != QMessageBox.Save:
                    return

        for item in self.items.values():
            value = item.value()
            if value and type(value) == str:
                value = value.strip()

            self.record.setValue(item.field(), value)

        for image_field in ImagesFields:
            item = self.items[image_field]
            if item.value():
                if hasattr(item.widget(), 'imageName'):
                    self.record.setValue(image_field, item.widget().imageName)

        # Paths to traits images are in reference
        for image_field in TraitsImagesFields:
            trait_field = image_field.replace('_image', '')
            trait_name = self.items[trait_field].value()
            if trait_name:
                # Gets image file name from reference.ref
                table_name = "ref_%s" % trait_field
                sql = "SELECT path FROM %s WHERE value=?" % table_name
                query = QSqlQuery(sql, self.model.reference.db)
                query.addBindValue(trait_name)
                query.exec_()
                if query.first():
                    self.record.setValue(image_field, query.record().value(0))
                else:
                    self.record.setNull(image_field)
            else:
                self.record.setNull(image_field)

        if self.tab.tags_item:
            tag_ids = self.tab.tags_item.getTags()
            self.record.setValue('tags', tag_ids)

        key = 'show_info/save_similar'
        show = settings.value(key, True, type=bool)
        if show:
            if not self.usedFields:
                if self.model.isExist(self.record):
                    msg_box = QMessageBox(
                        QMessageBox.Warning,
                        self.tr("Save"),
                        self.tr("Similar stamp already exists. Save?"),
                        QMessageBox.Save | QMessageBox.No,
                        self
                    )
                    msg_box.setDefaultButton(QMessageBox.No)
                    cb = QCheckBox(self.tr("Don't show this again"))
                    msg_box.setCheckBox(cb)
                    result = msg_box.exec_()
                    if result != QMessageBox.Save:
                        return
                    else:
                        if cb.isChecked():
                            settings.setValue(key, False)

        self.accept()

    def exec_(self):
        result = super().exec_()
        widget = self.items['region'].widget()
        if isinstance(widget, LineEditRef) and widget.hasDependents():
            widget.comboBox.editTextChanged.disconnect()

        widget = self.items['country'].widget()
        if isinstance(widget, LineEditRef) and widget.hasDependents():
            widget.comboBox.editTextChanged.disconnect()

        return result

    def getUsedFields(self):
        for item in self.items.values():
            index = self.record.indexOf(item.field())
            self.usedFields[index] = item.label().checkState()

        return self.usedFields

    def clear(self):
        self.tab.clear()
